METHOD create_badi_impl.

  DATA: lo_enh_impl TYPE REF TO if_enh_tool,
        lo_badi_impl_tool TYPE REF TO cl_enh_tool_badi_impl,

        lt_existing_badi_impls TYPE enh_badi_impl_data_it,

        ls_badi_impl TYPE enh_badi_impl_data,
        ls_filter_value TYPE enh_badiimpl_filter_value,
        ls_filter_impl TYPE enh_badi_filter_impl,
        ls_filter_root TYPE enh_badiimpl_filter_root,
        ls_filter_id TYPE enh_badiimpl_filter_id,

        lv_natual_number TYPE int4,

        lx_enh_root TYPE REF TO cx_enh_root.

  TRY.
* Try to find whether the enhancement implementation exists.
      lo_enh_impl = cl_enh_factory=>get_enhancement(
          lock                   = abap_true "Must lock it otherwise it cannot be deleted later
*          lock_4_activate        =
          enhancement_id         = iv_enh_impl_name
*        ddic_enh               =
*        virtual_subobject      =
*        before_export          =
*        rfcdestination         =
*        suppress_lang_dialog   =
*        repairmode             = 'U'
*        upgrade_mode           =
*        run_dark               =
*        cwb_handling           = ' '
*        is_xversionable_object =
*        versno                 =
*        bypassing_buffer       =
*        find_version           =
*        find_version_date      =
*        find_version_time      =
*        log_srcsystem          =
*        logid                  =
*        after_import           =
*        i_devclass             =
*        i_trkorr               =
*        suppress_repair_popup  =
*        request_language       = SY-LANGU
*        fallback_masterlang    =
             ).

*   If the enhancement implementation does not exist, the exception CX_ENH_IO_ERROR is thrown
*   and value of lo_enh_impl remains the same as before the method is called.
    CATCH cx_enh_root INTO lx_enh_root.

  ENDTRY.

  TRY.
*  Delete the enhancement implementation if found
      IF lo_enh_impl IS BOUND.

        lo_enh_impl->if_enh_object~delete(
*      EXPORTING
*        nevertheless_delete =
*        run_dark            =
*        scwb_call           = ABAP_FALSE
          CHANGING
            devclass            = cv_package
            trkorr              = cv_change_request
               ).

      lo_enh_impl->if_enh_object~unlock( ).

      ENDIF.


*  Try to create new enhancement implementation
      cl_enh_factory=>create_enhancement(
        EXPORTING
           enhname       = iv_enh_impl_name
           enhtype       = cl_abstract_enh_tool_redef=>credefinition
           enhtooltype   = cl_enh_tool_badi_impl=>tooltype
           compositename = iv_comp_enh_impl_name
*      scwb_call     = ' '
*      scwb_no_lock  = ' '
*      dark          =
*      orig_lang     =
*      check_mode    = ' '
*      genflag       =
      IMPORTING
          enhancement   = lo_enh_impl
      CHANGING
          trkorr        = cv_change_request
          devclass      = cv_package
      ).

* Enhancement is of type BAdI, so convert
      lo_badi_impl_tool ?= lo_enh_impl.
      lo_badi_impl_tool->set_spot_name( iv_enh_spot_name ).

* Prepare data for BAdI implementation creation
      CLEAR ls_badi_impl.
      ls_badi_impl-spot_name = iv_enh_spot_name.  "Enhancement spot
      ls_badi_impl-badi_name = iv_badi_def_name.  "BAdI definition name
      ls_badi_impl-impl_name = iv_badi_impl_name. "BAdI implementation name
      ls_badi_impl-impl_class = iv_impl_class_name. "Implementation class

* Other implementation configuration are hard-coded
      ls_badi_impl-active = 'X'.
      ls_badi_impl-is_default = 'X'.
      ls_badi_impl-impl_shorttext = 'BAdI implementation generated by FE Tool'.

* Create Filters
* Attention! only process string type filter with comparaotr '=' here.
      IF ( is_simple_string_filter IS NOT INITIAL  ).
*        Filter root
        lv_natual_number = 1.
        ls_filter_id-filter_name = is_simple_string_filter-filter_name.
        ls_filter_id-id = lv_natual_number.
        ls_filter_root-root = lv_natual_number.
        APPEND ls_filter_id TO ls_filter_root-filters.
        APPEND ls_filter_root TO ls_badi_impl-filter_root.

*         Filter value
        ls_filter_value-id = lv_natual_number.
        ls_filter_value-filter_name = is_simple_string_filter-filter_name.
        ls_filter_value-filter_type = 'S'.
        ls_filter_value-compare = '='.
        ls_filter_value-filter_string_value1 = is_simple_string_filter-filter_value.
        APPEND ls_filter_value TO ls_badi_impl-filter_values.

*          Filters
        ls_filter_impl-disj_idx = lv_natual_number.
        ls_filter_impl-conj_idx = lv_natual_number.
        ls_filter_impl-filter_name = is_simple_string_filter-filter_name.
        ls_filter_impl-filter_type = 'S'.
        ls_filter_impl-compare = '='.
        ls_filter_impl-filter_string_value1 = is_simple_string_filter-filter_value.
        APPEND ls_filter_impl TO ls_badi_impl-filters.

      ENDIF.

* Add BAdI implementations
      lo_badi_impl_tool->add_implementation( im_implementation = ls_badi_impl  ).

* Save
      lo_badi_impl_tool->if_enh_object~save( ).

* Activate
      lo_badi_impl_tool->if_enh_object~activate( ).

* Generate.
      lo_badi_impl_tool->if_enh_object~generate( ).

* Unlock.
      lo_badi_impl_tool->if_enh_object~unlock( ).

    CATCH cx_enh_root INTO lx_enh_root.
      RAISE EXCEPTION TYPE /SFT/cx_badi_impl_handling
        EXPORTING
          previous = lx_enh_root.
  ENDTRY.
ENDMETHOD.
